package encontrar;

import Util.Acentos;
import entidades.Posicao;
import entidades.Preprocessamento;
import entidades.Sentido;
import entidades.Status;
import entidades.Vias;
import entidades.ViasPosicao;
import entidades.ViasPosicao2;
import hibernate.HibernateUtil;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.hibernate.Session;

/**
 *
 * @author Gláucio
 */
public class Encontrar {

  private String via;
  private String sentido;
  private String status;
  private String posicao;
  private String posicao2;
  private String preProcessamento;
  private String analiseLexica;
  private String resto;
  private List<Sentido> classesSentido;
  private List<Posicao> classesPosicao;
  private List<Status> classesStatus;
  private List<Vias> classesVias;
  private List<Preprocessamento> classesPreProcessamento;
  private List<ViasPosicao> classesViasPosicao;
  private List<ViasPosicao2> classesViasPosicao2;

  public Encontrar() {
    Session s = HibernateUtil.getSessionFactory().openSession();
    classesSentido = s.createQuery("from Sentido order by bit_length(nomeSentido) desc").list();
    classesPosicao = s.createQuery("from Posicao order by prioridade").list();
    classesStatus = s.createQuery("from Status order by bit_length(nomeStatus) desc").list();
    classesVias = s.createQuery("from Vias order by bit_length(nomeVia) desc").list();
    classesPreProcessamento = s.createQuery("from Preprocessamento order by bit_length(original) desc").list();
    classesViasPosicao = s.createQuery("from ViasPosicao order by bit_length(nomeViaPosicao) desc").list();
    classesViasPosicao2 = s.createQuery("from ViasPosicao2 order by bit_length(nomeViaPosicao) desc").list();
  }

  public String getPosicao() {
    return posicao.trim();
  }

  public String getPosicao2() {
    return posicao2.trim();
  }

  public String getSentido() {
    return sentido.trim();
  }

  public String getStatus() {
    return status.trim();
  }

  public String getVia() {
    return via.trim();
  }

  public String getPreProcessamento() {
    return preProcessamento;
  }

  public String getAnaliseLexica() {
    return analiseLexica;
  }

  public String getResto() {
    return resto;
  }

  private String preProcessamento(String post) {
    for (int i = 0; i < classesPreProcessamento.size(); i++) {
      Preprocessamento v = classesPreProcessamento.get(i);
      String origem = v.getOriginal().replace("\n", "");
      String substituir = v.getSubstituta().replace("\n", "");
      post = post.replace(" " + origem + " ", " " + substituir + " ");
    }

    return post;
  }

  public String encontarClasses(String frase) {
    via = "";
    sentido = "";
    status = "";
    posicao = "";
    posicao2 = "";
    preProcessamento = "";
    analiseLexica = "";
    resto = "";
    frase = Acentos.retirarAcentos(frase.toUpperCase());
    frase = preProcessamento(frase);
    preProcessamento = frase; //para retornar
    int cont = 4;

    //1.1) Localizar a Posicao usando Analizador Léxico
    ListaTokens l = new ListaTokens();
    l.setViasPosicao(classesViasPosicao);
    l.setVias(classesVias);
    List<Token> a = l.separaTokens(frase);

    for (int i = 0; i < a.size(); i++) {
      Token t = a.get(i);
      analiseLexica += t.getValor() + " - " + t.getTipo() + " - " + t.getPosicao() + " - " + t.getTamanho() + "\n";
    }

    for (int x = 0; x < (a.size() - 3); x++) {
      Token t0 = a.get(x + 0);
      Token t1 = a.get(x + 1);
      Token t2 = a.get(x + 2);
      Token t3 = a.get(x + 3);

      //{entre} + {via} + {e} + {via}
      if ((t0.getTipo() == Token.Tipo.ENTRE) && (t1.getTipo() == Token.Tipo.ViaPosicao) && (t2.getTipo() == Token.Tipo.E) && (t3.getTipo() == Token.Tipo.ViaPosicao)) {
        posicao = t0.getValor() + " " + t1.getValor() + " " + t2.getValor() + " " + t3.getValor();
        cont--;
        frase = frase.replace(posicao, ""); //retira a posicao da frase
        break;
      } else if ((t0.getTipo() == Token.Tipo.ENTRE) && (t1.getTipo() == Token.Tipo.ViaPosicao) && (t2.getTipo() == Token.Tipo.ATE) && (t3.getTipo() == Token.Tipo.ViaPosicao)) {
        posicao = t0.getValor() + " " + t1.getValor() + " " + t2.getValor() + " " + t3.getValor();
        cont--;
        frase = frase.replace(posicao, ""); //retira a posicao da frase
        break;
      } else if ((t0.getTipo() == Token.Tipo.DA) && (t1.getTipo() == Token.Tipo.ViaPosicao) && (t2.getTipo() == Token.Tipo.ATE) && (t3.getTipo() == Token.Tipo.ViaPosicao)) {
        posicao = t0.getValor() + " " + t1.getValor() + " " + t2.getValor() + " " + t3.getValor();
        cont--;
        frase = frase.replace(posicao, ""); //retira a posicao da frase
        break;
      } else if ((t0.getTipo() == Token.Tipo.DO) && (t1.getTipo() == Token.Tipo.ViaPosicao) && (t2.getTipo() == Token.Tipo.ATE) && (t3.getTipo() == Token.Tipo.ViaPosicao)) {
        posicao = t0.getValor() + " " + t1.getValor() + " " + t2.getValor() + " " + t3.getValor();
        cont--;
        frase = frase.replace(posicao, ""); //retira a posicao da frase
        break;
      }else if ((t0.getTipo() == Token.Tipo.DESDE) && (t1.getTipo() == Token.Tipo.ViaPosicao) && (t2.getTipo() == Token.Tipo.ATE) && (t3.getTipo() == Token.Tipo.ViaPosicao)) {
        posicao = t0.getValor() + " " + t1.getValor() + " " + t2.getValor() + " " + t3.getValor();
        cont--;
        frase = frase.replace(posicao, ""); //retira a posicao da frase
        break;
      }
    }

    //1.2) Localizar o Posicao usando apenas BD
    for (int i = 0; i < classesViasPosicao2.size(); i++) {
      ViasPosicao2 v = classesViasPosicao2.get(i);
      String nomeViaPosicao = preProcessamento(v.getNomeViaPosicao().replace("\r", ""));
      int idx = frase.indexOf(nomeViaPosicao);
      if (idx >= 0) {
        posicao2 = nomeViaPosicao;
        frase = frase.replace(posicao2, ""); //retira o sentido da frase
        cont--;
        break; //mostra so o primeiro
      }
    }

    //1.3) localizar a Posicao usando expressoes Regulares
    if (cont == 4) {
      for (int i = 0; i < classesPosicao.size(); i++) {
        Posicao pos = classesPosicao.get(i);
        String nomePosicao = pos.getNomePosicao().replace("\r", "");
        Pattern p = Pattern.compile(nomePosicao);
        Matcher m = p.matcher(frase);
        if (m.find()) {
          posicao += m.group();
          posicao2 = posicao;
          frase = frase.replace(posicao, ""); //retira a posicao da frase
          cont--;
          break; //mostra so o primeiro
        }
      }
    }

    //2) Localizar o Sentido
    for (int i = 0; i < classesSentido.size(); i++) {
      Sentido v = classesSentido.get(i);
      String nomeSentido = preProcessamento(v.getNomeSentido().replace("\r", ""));
      int idx = frase.indexOf(nomeSentido);
      if (idx >= 0) {
        sentido = nomeSentido;
        frase = frase.replace(sentido, ""); //retira o sentido da frase
        cont--;
        break; //mostra so o primeiro
      }
    }

    //3) Localizar o Status
    for (int i = 0; i < classesStatus.size(); i++) {
      Status v = classesStatus.get(i);
      String nomeStatus = preProcessamento(v.getNomeStatus().replace("\r", ""));
      int idx = frase.indexOf(nomeStatus);
      if (idx >= 0) {
        status = nomeStatus;
        frase = frase.replace(status, ""); //retira o status da frase
        cont--;
        break; //mostra so o primeiro
      }
    }

    //4) Localizar a Via
    for (int i = 0; i < classesVias.size(); i++) {
      Vias v = classesVias.get(i);
      String nomeVia = preProcessamento(v.getNomeVia().replace("\r", ""));
      int idx = frase.indexOf(nomeVia);
      if (idx >= 0) {
        via = nomeVia;
        frase = frase.replace(via, ""); //retira a via da frase
        cont--;
        break; //mostra so o primeiro
      }
    }
    resto = frase;

    return ("1) Sentido: " + sentido + "\n" +
            "2) Via: " + via + "\n" +
            "3) Status: " + status + "\n" +
            "4) Posição Análise Sintática: " + posicao + "\n" +
            "5) Posição BD: " + posicao2);

  }
  
   public static void main(String args[]) {
     Encontrar e =  new Encontrar();
     System.out.println(e.preProcessamento(" DIREÇÃO A "));
   }
  
}
